package gui.ex.paint;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/*
 * Written by SUN
 */
public class SwingPaintDemo {

	public static void main(String[] args) {

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createAndShowGUI();
			}
		});
	}

	private static void createAndShowGUI() {
		System.out.println("Created GUI on EDT? "
				+ SwingUtilities.isEventDispatchThread());
		JFrame f = new JFrame("Swing Paint Demo");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.add(new MyPanel());
		f.setSize(250, 250);
		f.setVisible(true);
	}

	public static class MyPanel extends JPanel {

		RedSquare redSquare = new RedSquare();

		public MyPanel() {

			setBorder(BorderFactory.createLineBorder(Color.black));
			
			addMouseListener(new MouseAdapter() {
				public void mousePressed(MouseEvent e) {
					moveSquare(e.getX(), e.getY());
				}
			});

			addMouseMotionListener(new MouseAdapter() {
				public void mouseDragged(MouseEvent e) {
					moveSquare(e.getX(), e.getY());
				}
			});

		}

		private void moveSquare(int x, int y) {

			// Current square state, stored as final variables
			// to avoid repeat invocations of the same methods.
			final int CURR_X = redSquare.getX();
			final int CURR_Y = redSquare.getY();
			final int CURR_W = redSquare.getWidth();
			final int CURR_H = redSquare.getHeight();
			final int OFFSET = 1;

			if ((CURR_X != x) || (CURR_Y != y)) {

				// The square is moving, repaint background
				// over the old square location.
				repaint(CURR_X, CURR_Y, CURR_W + OFFSET, CURR_H + OFFSET);

				// Update coordinates.
				redSquare.setX(x);
				redSquare.setY(y);

				// Repaint the square at the new location.
				repaint(redSquare.getX(), redSquare.getY(),
						redSquare.getWidth() + OFFSET, redSquare.getHeight()
								+ OFFSET);
			}
		}

		public Dimension getPreferredSize() {
			return new Dimension(250, 200);
		}

		public void paintComponent(Graphics g) {
			// Never forget the first call to paint :)
		    // Let UI Delegate paint first, which 
		    // includes background filling since 
		    // this component is opaque.
			super.paintComponent(g);
			g.drawString("This is my custom Panel!", 10, 20);

			redSquare.paintSquare(g);
		}

		public static class RedSquare {

			private int xPos = 50;
			private int yPos = 50;
			private int width = 20;
			private int height = 20;

			public void setX(int xPos) {
				this.xPos = xPos;
			}

			public int getX() {
				return xPos;
			}

			public void setY(int yPos) {
				this.yPos = yPos;
			}

			public int getY() {
				return yPos;
			}

			public int getWidth() {
				return width;
			}

			public int getHeight() {
				return height;
			}

			public void paintSquare(Graphics g) {
				g.setColor(Color.RED);
				g.fillRect(xPos, yPos, width, height);
				g.setColor(Color.BLACK);
				g.drawRect(xPos, yPos, width, height);
			}
		}
	}
}